import cv2
import numpy as np
from utils import capture_screenshot
from settings import sleep_options

def crop_border(image, border_size=4):
    """
    去掉图片边框
    :param image: 输入图片
    :param border_size: 边框大小
    :return: 去掉边框后的图片
    """
    return image[border_size:-border_size, border_size:-border_size]

def is_whiteboard(image, threshold=200, ratio=0.9):
    """
    判断图片是否为白板
    :param image: 输入图片
    :param threshold: 像素值阈值，高于此值认为是白色
    :param ratio: 白色像素占比阈值，超过此比例认为是白板
    :return: True 或 False
    """
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    white_pixels = np.sum(gray > threshold)
    total_pixels = gray.size
    # 计算白色像素占比
    return (white_pixels / total_pixels) > ratio

# 结合模板图片路径和对应阈值
# 9s和7s比较像提高阈值，字牌可以适当降低阈值
template_info = [
    ("images/card/1.png", 0.6),
    ("images/card/2.png", 0.6),
    ("images/card/3.png", 0.6),
    ("images/card/4.png", 0.6),
    ("images/card/5.png", 0.6),
    ("images/card/6.png", 0.8),
    ("images/card/7.png", 0.6),
    ("images/card/8.png", 0.6),
    ("images/card/9.png", 0.6),
    ("images/card/10.png", 0.6),
    ("images/card/11.png", 0.6),
    ("images/card/12.png", 0.6),
    ("images/card/13.png", 0.6)
]

template_info_chelun = [
    ("images/card/3p.png", 0.6),
    ("images/card/4p.png", 0.6),
    ("images/card/5p.png", 0.6),
    ("images/card/6p.png", 0.6),
    ("images/card/7p.png", 0.6)
]

# 一次性读取所有模板图片
templates = [cv2.imread(path, cv2.IMREAD_COLOR) for path, _ in template_info]
templates_chelun = [cv2.imread(path, cv2.IMREAD_COLOR) for path, _ in template_info_chelun]

def match_template(image, is_chelun=False):
    """
    与模板图片进行匹配，返回匹配度最高的模板序号和所有匹配相似度
    :param image: 输入图片
    :param template_info: 包含模板图片路径和对应阈值的列表
    :param templates: 已读取的模板图片列表
    :return: 匹配度最高的模板序号，所有匹配相似度列表
    """
    if is_chelun:
        template_info_final = template_info_chelun
        templates_final = templates_chelun
    else :
        template_info_final = template_info
        templates_final = templates

    # 先判断是否为白板
    if is_whiteboard(image):
        similarities = [0] * len(template_info_final)
        if is_chelun:
            return 0, similarities
        whiteboard_index = 11
        similarities[whiteboard_index - 1] = 1
        return whiteboard_index, similarities

    best_match_index = 0
    best_match_value = -1
    similarities = [0] * len(template_info_final)

    # 遍历模板
    for i, (_, threshold) in enumerate(template_info_final):
        if i == 10:  # 跳过白板模板（索引为 10，对应第 11 张模板）
            continue
        template = templates_final[i]
        result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
        similarities[i] = max_val
        # 检查相似度是否超过对应模板的阈值
        if max_val > best_match_value and max_val >= threshold:
            best_match_value = max_val
            best_match_index = i

    # 相似度阈值判断
    if best_match_value < 0:
        best_match_index = -1
    return best_match_index + 1, similarities

def read_hand(hand_image=None, region_name=None, is_chelun=False):
    """
    读取麻将手牌图片，进行处理并匹配模板
    :param image: 输入图片
    :return: 手牌数组，数组中是模板的序号
    """
    if region_name is not None:
        hand_image = capture_screenshot(region_name=region_name, delay=sleep_options["读牌截图"])

    # 读取手牌图片
    hand_width = hand_image.shape[1]

    # 每张牌的宽度
    tile_width = 75

    # 手动调整后的 start_x 数组
    start_x_values = [3, 78, 152, 226, 301, 376, 451, 525, 599, 674, 749, 824, 898]
    if hand_width > 975:
        start_x_values = [3, 78, 152, 226, 301, 376, 451, 525, 599, 674, 749, 824, 898, 996]

    tiles = []
    for i in range(len(start_x_values)):
        start_x = start_x_values[i]
        end_x = start_x + tile_width
        tile = hand_image[:, start_x:end_x]
        tiles.append(tile)

    # 去掉边框并匹配模板
    hand_array = []
    all_similarities = []
    for i, tile in enumerate(tiles):
        # 去掉边框
        cropped_tile = crop_border(tile)
        # 调整大小与模板一致
        first_template = templates[0]
        resized_tile = cv2.resize(cropped_tile, (first_template.shape[1], first_template.shape[0]))

        # 保存处理后的手牌图片
#         save_path = f"images/tem{i + 1}.png"
#         cv2.imwrite(save_path, resized_tile)
#         print(f"已保存处理后的第 {i + 1} 张手牌图片: {save_path}")

        # 匹配模板
        match_index, similarities = match_template(resized_tile, is_chelun)
        hand_array.append(match_index)
        all_similarities.append(similarities)
        # 格式化输出相似度，保留 4 位小数
#         formatted_similarities = [f"{sim:.4f}" for sim in similarities]
#         print(f"第 {i + 1} 张手牌与各模板的相似度: {formatted_similarities}")

    return hand_array

if __name__ == "__main__":
    # 手牌图片路径
#     hand_image = cv2.imread("images/card/test_screenshot2.png", cv2.IMREAD_COLOR)
    # test_screenshot2.png期望得到[1, 3, 0, 0, 4, 4, 0, 0, 0, 6, 6, 7, 11]
    # test_screenshot3.png期望得到[2, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 12]
    # test_screenshot4.png期望得到[0, 0, 4, 5, 0, 0, 0, 0, 0, 6, 10, 11, 12]
    # test_screenshot5.png期望得到[0, 0, 0, 5, 5, 5, 0, 6, 8, 9, 10, 13, 13]

    # 读取手牌
    hand_array = read_hand(region_name="手牌区带模切", is_chelun=True)
    last_card = hand_array[-1]
    print("手牌数组:", hand_array)
    print(last_card)
